// $Id: library.hpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#ifndef XPCOM_LIBRARY_HPP
#define XPCOM_LIBRARY_HPP

#include <xpcom/config.hpp>
#include <xpcom/types.hpp>
#include <xpcom/ptr.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

class nsIComponentManager;
class nsIComponentRegistrar;
class nsIDebug;
class nsIDirectoryServiceProvider;
class nsIFile;
class nsILocalFile;
class nsIMemory;
class nsIModule;
class nsIServiceManager;
class nsITraceRefcnt;

namespace xpcom {

typedef result_t
(XPCOM_LIB_CALLBACK *get_module_proc)(
        nsIComponentManager* component_manager,
        nsIFile* location,
        nsIModule** module);

struct static_module_info
{
    const char* name;
    get_module_proc get_module;
};

//
// Provides XPCOM library related functions.
// Also will init XPCOM in its constructor, and shutdown XPCOM in its
// destructor.
//
class XPCOM_DECL library
{
public:
    library();

    library(noref_ptr<nsIFile> bin_dir,
            noref_ptr<nsIDirectoryServiceProvider> dir_provider);

    library(noref_ptr<nsIFile> bin_dir,
            noref_ptr<nsIDirectoryServiceProvider> dir_provider,
            const static_module_info* static_components,
            uint32_t component_count);

    ~library();

    //
    // Library services accessors
    //
    static ref_ptr<nsIServiceManager> service_manager();
    static ref_ptr<nsIComponentManager> component_manager();
    static ref_ptr<nsIComponentRegistrar> component_registrar();
    static ref_ptr<nsIMemory> memory_manager();
    static ref_ptr<nsIDebug> debug_manager();
    static ref_ptr<nsITraceRefcnt> trace_refcnt_manager();

private:
    nsIServiceManager* service_manager_;

    // Not copyable
    library(const library&);
    const library& operator=(const library&);
};

//
// Makes new file instance
//
XPCOM_DECL ref_ptr<nsIFile> new_file(
        const wstring& path, bool follow_links = false);

XPCOM_DECL ref_ptr<nsIFile> new_native_file(
        const string& path, bool follow_links = false);

XPCOM_DECL ref_ptr<nsILocalFile> new_local_file(
        const wstring& path, bool follow_links = false);

XPCOM_DECL ref_ptr<nsILocalFile> new_native_local_file(
        const string& path, bool follow_links = false);

} // namespace xpcom

//
// Convenience macro for declaring static modules
//
#define XPCOM_STATIC_MODULE_PROC(name) name##_NSGetModule

#define XPCOM_STATIC_MODULE_PROC_DECL(name) \
    extern "C" ::xpcom::result_t XPCOM_LIB_CALLBACK \
    XPCOM_STATIC_MODULE_PROC(name)(nsIComponentManager*, nsIFile*, nsIModule**);

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // XPCOM_LIBRARY_HPP
